package com.zxcl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxcl.constant.BusinessEnum;
import com.zxcl.domain.Basket;
import com.zxcl.domain.ShopDetail;
import com.zxcl.domain.Sku;
import com.zxcl.ex.BusinessException;
import com.zxcl.feign.CartProdFeign;
import com.zxcl.feign.CartStoreFeign;
import com.zxcl.mapper.BasketMapper;
import com.zxcl.model.CartItem;
import com.zxcl.model.Result;
import com.zxcl.model.ShopCart;
import com.zxcl.service.BasketService;
import com.zxcl.utils.AuthUtil;
import com.zxcl.vo.CartMoneyVO;
import com.zxcl.vo.CartVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> implements BasketService{


    @Autowired
    private CartProdFeign cartProdFeign;

    @Autowired
    private CartStoreFeign cartStoreFeign;


    /**
     * 查询购物车数量
     *
     * @return
     */
    @Override
    public Integer basketCount() {
        String openId = AuthUtil.getOpenId();
        List<Object> list = this.getBaseMapper().selectObjs(new QueryWrapper<Basket>()
                .select("IFNULL(SUM(prod_count),0)")
                .eq("open_id", openId)
        );
        Object o = list.get(0);
        return Integer.parseInt(o.toString());
    }

    /**
     * 添加或者修改购物车数量
     *
     * @param basket
     * @return
     */
    @Override
    public Integer changeBasket(Basket basket) {
        //得到当前用户的购物车的商品总数
        Integer allCount = basketCount();
        //得到现在添加的商品总数
        int finalCount = allCount + basket.getProdCount();//2+(-1)
        if (finalCount > 100) {
            throw new BusinessException("购物车商品达到上限");
        }
        String openId = AuthUtil.getOpenId();
        Basket oldBasket = getBaseMapper().selectOne(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getOpenId, openId)
                .eq(Basket::getSkuId, basket.getSkuId())
        );

        if(ObjectUtils.isEmpty(oldBasket)){
           //添加
            basket.setCreateTime(new Date());
            basket.setOpenId(openId);
            return this.getBaseMapper().insert(basket);
        }
        //修改
        int prodCount = oldBasket.getProdCount() + basket.getProdCount();
        if (prodCount <= 0) {
            throw new BusinessException("购物车商品数量不能小于0");
        }
        oldBasket.setProdCount(prodCount);
        oldBasket.setCreateTime(new Date());
        return getBaseMapper().updateById(oldBasket);
    }

    /**
     * 购物车详情
     * 要查询的表  basket  shop_detail   sku
     * 根据openId拿到当前会员购物车的所有信息List<Basket> basketList
     * 取出BasketList里面的shopIds  Set<>
     * 取出BasketList里面的skuIds  Set<>
     * 远程调用store-service 拿店铺信息
     * 远程调用 product-service 拿sku的信息
     * @return
     */
    @Override
    public CartVO cartInfo() {
        CartVO cartVO=new CartVO();
        //根据openId拿到当前会员购物车的所有信息List<Basket> basketList
        String openId = AuthUtil.getOpenId();
        List<Basket> basketList=this.getBaseMapper().selectList(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getOpenId,openId)
                .orderByDesc(Basket::getCreateTime)
        );
        if (CollectionUtils.isEmpty(basketList)) {
            return cartVO;
        }
        //拿商品  从basketList取出商品所有ID
        List<Long> skuIds=basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
        Result<List<Sku>> skuResult = cartProdFeign.getSkusByIds(skuIds);
        //处理远程调用失败的情况
        if (skuResult.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException(skuResult.getMsg());
        }
        //取出sku的数据
        List<Sku> skuList = skuResult.getData();
        //把skuList转成Map<SkuId,Sku>
        Map<Long,Sku> skuMap=skuList.stream()
                .collect(Collectors.toMap(Sku::getSkuId,sku -> sku));
        //拿店铺  取出里面所有的shopIds
        Set<Long> shopIds=basketList.stream().map(Basket::getShopId).collect(Collectors.toSet());
        Result<List<ShopDetail>> shopDetailsResult = cartStoreFeign.getShopDetailsByIds(shopIds);
        //处理远程调用失败的情况
        if (shopDetailsResult.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException(shopDetailsResult.getMsg());
        }
        //取出所有的店铺数据
        List<ShopDetail> shopDetailList = shopDetailsResult.getData();
        //把 List<ShopDetail>  转成Map<ShopId,ShopDetail>
        Map<Long,ShopDetail> shopDetailMap=shopDetailList
                .stream().collect(Collectors.toMap(ShopDetail::getShopId,shopDetail -> shopDetail));
        //组装数据
        List<ShopCart> shopCarts=new ArrayList<>();
        basketList.forEach(basket -> {
            //取出店铺ID
            Long shopId = basket.getShopId();
            //判读shopCarts里面之前这个店铺有没有放数据
            List<ShopCart> shopCartList = shopCarts.stream().filter(shopCart -> shopCart.getShopId().equals(shopId)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(shopCartList)) {
                //说明这个店铺在shopCarts里面还没有数据
                ShopCart shopCart = new ShopCart();
                shopCart.setShopId(shopId);
                //根据shopId到shopDetailMap取店铺数据
                ShopDetail shopDetail = shopDetailMap.get(shopId);
                shopCart.setShopName(shopDetail.getShopName());
                shopCart.setShopLogo(shopDetail.getShopLogo());
                shopCart.setShopLink(shopDetail.getShopAddress());
                // 创建一个商品集合
                List<CartItem> cartItems = new ArrayList<>();
                CartItem cartItem=new CartItem();
                BeanUtils.copyProperties(basket, cartItem);
                //去skuMap里面拿sku的信息
                Sku sku = skuMap.get(basket.getSkuId());
                //再把sku的信息复制到cartItem
                BeanUtils.copyProperties(sku, cartItem);
                cartItems.add(cartItem);
                shopCart.setShopCartItems(cartItems);
                shopCarts.add(shopCart);
            }else{
                // 取出店铺
                ShopCart shopCart = shopCartList.get(0);
                List<CartItem> cartItems = shopCart.getShopCartItems();
                CartItem cartItem=new CartItem();
                BeanUtils.copyProperties(basket, cartItem);
                //去skuMap里面拿sku的信息
                Sku sku = skuMap.get(basket.getSkuId());
                //再把sku的信息复制到cartItem
                BeanUtils.copyProperties(sku, cartItem);
                cartItems.add(cartItem);
                shopCart.setShopCartItems(cartItems);
            }
        });
        //把shopCarts放到cartVo
        cartVO.setShopCarts(shopCarts);
        return cartVO;
    }

    /**
     * 计算购物车选中商品的价格
     *
     * @param basketIds
     * @return
     */
    @Override
    public CartMoneyVO calculateBasketMoney(List<Long> basketIds) {
        CartMoneyVO cartMoneyVO = new CartMoneyVO();
        if (CollectionUtils.isEmpty(basketIds)) {
            return cartMoneyVO;
        }
        List<Basket> baskets = getBaseMapper().selectBatchIds(basketIds);
        List<Long> skuIds = baskets.stream().map(Basket::getSkuId).collect(Collectors.toList());
        Result<List<Sku>> skuResult = cartProdFeign.getSkusByIds(skuIds);
        if (skuResult.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException(skuResult.getMsg());
        }
        List<Sku> skuList = skuResult.getData();
        Map<Long, BigDecimal> priceMap = skuList.stream()
                .collect(Collectors.toMap(Sku::getSkuId, Sku::getPrice));
        List<BigDecimal> oneMoneys = new ArrayList<>();
        baskets.forEach(basket -> {
            Integer prodCount = basket.getProdCount();
            BigDecimal price = priceMap.get(basket.getSkuId());
            BigDecimal oneMoney = price.multiply(new BigDecimal(prodCount.toString()));
            oneMoneys.add(oneMoney);
        });

        BigDecimal totalMoney = oneMoneys.stream().reduce(BigDecimal::add).get();

        // 如果总价小于99  有6元运费

        cartMoneyVO.setTotalMoney(totalMoney);
        cartMoneyVO.setFinalMoney(totalMoney);
        if (totalMoney.compareTo(new BigDecimal("99")) < 0) {
            cartMoneyVO.setTransMoney(new BigDecimal("6"));
            cartMoneyVO.setFinalMoney(totalMoney.add(new BigDecimal("6")));
        }
        return cartMoneyVO;

    }

}
